package com.ai.service.made.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.ai.common.CommonResponse;
import com.ai.entity.BasePage;
import com.ai.entity.alarm.RecordAlarmVO;
import com.ai.entity.file.Audio;
import com.ai.entity.file.AudioPage;
import com.ai.entity.function.FunctionPO;
import com.ai.entity.server.ServerPO;
import com.ai.mapper.made.AudioMapper;
import com.ai.mapper.made.ServerMapper;
import com.ai.model.dto.CoalAudioVo;
import com.ai.service.made.AudioService;
import com.ai.service.made.FunctionService;
import com.ai.util.FileUploaderUtil;
import com.ai.util.SecurityUtils;
import com.ai.util.SftpFileUploaderUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author：xiaosheng
 * @Date：2024/5/15 10:18
 */
@Slf4j
@Service
public class AudioServiceImpl extends ServiceImpl<AudioMapper, Audio> implements AudioService {

    @Resource
    AudioMapper audioMapper;

    @Resource
    Environment environment;

    @Autowired
    ServerMapper serverMapper;

    @Resource
    private FunctionService functionService;

    @Resource
    private FileUploaderUtil fileUploaderUtil;

    /**
     * 文件上传
     *
     * @param multipartFile
     * @return
     */
    @Transactional
    @Override
    public CommonResponse upload(MultipartFile multipartFile, String name) {

        //获取文件存储的地址
        String url = environment.getProperty("audioUploadPath.url");

        //获取文件名
        String originalFilename = multipartFile.getOriginalFilename();

        String urlName = url + originalFilename;

        Audio audio1 = getOne(new QueryWrapper<Audio>().eq("audio_name", originalFilename));

        File file1 = new File(url, originalFilename);


        if (audio1 != null || file1.exists()) {
            return CommonResponse.error("该文件内存中已经存在");
        }


        // 获取音频文件的后缀名
        String subffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length());

        //构建文件对象
        File file = new File(url);
        //创建需要存储音频的文件夹
        if (!file.exists()) {
            boolean mkdir = file.mkdir();
            if (!mkdir) {
                log.error("创建文件夹异常");
            }
        }
        try {
            //获取文件输入流
            InputStream inputStream = multipartFile.getInputStream();
            //构建文件输出流
            FileOutputStream outputStream = new FileOutputStream(urlName);
            byte[] bytes = new byte[1024];
            int bytesread;
            while ((bytesread = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, bytesread);
            }

            Audio audio = new Audio();
            audio.setAudioName(originalFilename);
            audio.setRemark(name);
            audio.setSuffix(subffix);
            audio.setUrl(url);
            audio.setCreateTime(DateTime.now());
            audio.setUpdateTime(DateTime.now());
            save(audio);
            log.info("保存的音频信息为：{}", audio);

            outputStream.close();
            inputStream.close();

            return CommonResponse.ok("音频文件上传成功");
        } catch (IOException e) {
            log.error("文件上传异常,{}", e.getMessage());
            e.printStackTrace();
        }
        return CommonResponse.ok();
    }


    /**
     * 通过id获取文件信息
     *
     * @param id
     * @return
     */
    @Override
    public Audio oneById(Integer id) {

        Audio byId = getById(id);

        return byId;
    }


    /**
     * 修改音频文件名称
     *
     * @param audio
     * @return
     */
    @Override
    public CommonResponse modifyInfo(Audio audio) {

        //通过音频文件id查询出相关文件信息
        Audio byId = getById(audio.getId());
        //拿到需要修改音频文件的文件名
        String remark = audio.getRemark();

        //判断是否为同一名字
        if (byId.getRemark().equals(remark)) {
            return CommonResponse.error("名称相同,修改失败");
        }

        byId.setRemark(remark);
        if (updateById(byId)) {
            return CommonResponse.ok("修改成功");
        } else {
            return CommonResponse.ok("修改失败");
        }
    }

    @Override
    public CommonResponse delete(Audio audio) {

        if (ObjectUtils.isEmpty(audio.getId())){
            return CommonResponse.error("文件Id为空");
        }

        try {
            Audio audio1 = audioMapper.selectById(audio.getId());
            String audioName = audio1.getAudioName();

            //获取文件存储的地址
            String url = environment.getProperty("fileUploadPath.url");
            //删除本地文件
            File file = new File(audio1.getUrl());
            if (file.exists()) {
                boolean fileDel = file.delete();
            }
        }catch (Exception e){
            log.error("===========================   音频本地文件删除失败   ===========================");
            e.printStackTrace();
        }
        removeById(audio.getId());
        return CommonResponse.ok("删除成功");
    }


    /**
     * 本地文件上传到服务器
     *
     * @param fileId
     * @param serverId
     * @return
     */
    @Override
    public CommonResponse uploadToServer(Integer fileId, Integer serverId) {

        if (fileId == null) {
            return CommonResponse.error("文件Id为空");
        }

        if (serverId == null) {
            return CommonResponse.error("服务器Id为空");
        }

        //根据文件Id查询数据库是否存在
        Audio byId = getById(fileId);
        if (Objects.isNull(byId)) {
            return CommonResponse.error("数据库中不存在该文件");
        }

        //根据服务器Id查询该服务器在数据库中是否存在
        ServerPO serverPO = serverMapper.selectById(serverId);
        if (Objects.isNull(serverPO)) {
            return CommonResponse.error("数据库中不存在该服务器");
        }

        String audioName = byId.getAudioName();
        // 远程服务器连接参数
        String host = "192.168.8.194";
        int port = 22;
        String username = "jiaokang";
        String password = "jiaokang";
        String remoteDirectory = serverPO.getDeployPath()+"/"+"audio";

        // 创建上传器对象并调用上传方法
        try {
            SftpFileUploaderUtil uploader = new SftpFileUploaderUtil(host, username, password, remoteDirectory);
            uploader.uploadFile(audioName);
        } catch (Exception e) {
            log.error("文件上传异常，{}", e.getMessage());
        }
        return CommonResponse.ok();
    }


    @Override
    public CommonResponse selectByPage(AudioPage audioPage) {
        IPage<Audio> voIPage = new BasePage<>();
        QueryWrapper<Audio> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        queryWrapper = audioPage.getQuery(queryWrapper);
        IPage<Audio> page = page(voIPage, queryWrapper);
        List<Audio> records = page.getRecords();
        List<Audio> audioList = records.stream().map(audio -> {
            FunctionPO funByType = functionService.getFunByType(Integer.valueOf(audio.getFunctionType()));
            audio.setFunctionType(funByType.getNickname());
            return audio;
        }).collect(Collectors.toList());
        page.setRecords(audioList);
        return CommonResponse.ok(page);
    }

    @Override
    public CommonResponse uploadAudio(MultipartFile file, CoalAudioVo coalAudioVo) {

        FunctionPO functionPO = functionService.getById(coalAudioVo.getFunctionId());
        int type = functionPO.getType();
        List<Audio> audioList = this.list(new QueryWrapper<Audio>().eq("function_type", type));
        if (!CollectionUtils.isEmpty(audioList)) {
            throw new RuntimeException("目标算法已绑定音频，请删除后重新上传");
        }

        //文件存储路径
        HashMap<String, String> hashMap = fileUploaderUtil.uploadAudio(file, coalAudioVo);
        if (CollectionUtils.isEmpty(hashMap)){
            throw new RuntimeException("音频文件上传失败");
        }

        Audio audio = new Audio();
        audio.setAudioName(hashMap.get("originalFilename"));
        audio.setRemark(coalAudioVo.getName());
        audio.setUrl(hashMap.get("filePath"));
        audio.setCreateTime(DateTime.now());
        audio.setUpdateTime(DateTime.now());
        audio.setCreateUser(SecurityUtils.getLoginUserName());
        audio.setUpdateUser(SecurityUtils.getLoginUserName());
        audio.setFunctionType(String.valueOf(type));

        boolean save = save(audio);
        return save?CommonResponse.ok("音频上传成功"):CommonResponse.error("音频上传失败");

    }
}
